package lock;

import org.junit.Test;

import java.util.concurrent.TimeUnit;

/**
 * 8中锁使用案例
 * <pre>
 *    题目：谈谈你对多线程的理解，8锁案例
 *    口诀： 线程 操作 资源类
 *    8锁案例说明：
 *    1 标准访问有ab两个线程，请问先打印邮件还是短信 ————————邮件->短信
 *    2 对sendMail方法加线程休眠3s呢？——————邮件->短信
 *    3 添加hello()普通方法，先打印邮件还是hello——————hello->邮件
 *    4 两个phone对象，一个打印邮件，一个打印短信？————————短信->邮件
 *    5 phone对象，两个静态方法？——————邮件->短信
 *    6 两个phone对象，两个静态——————邮件->短信
 *    7 一个phone，一个成员，一个静态——————短信->邮件
 *    8 2个phone，一个成员，一个静态——————短信->邮件
 *    总结：
 *    1. 对类普通方法加synchronized,锁住的是对象实例(this)，相同的实例存在竞态，不同实例不存在竞态。
 *    2. 对类静态方法加synchronized，锁住的是整个类对象(class)，类所有的实例之间都会存在竞态。
 *    3. 对于synchronized同步代码块，锁住的是括号中的对象。
 * </pre>
 *
 * @author codefish
 * @version 1.0
 * @date 2022/07/30 上午 10:52
 */
public class LockDemoTest {

    @Test
    public void testLock1() {
        Phone phone = new Phone();
        Phone phone2 = new Phone();
        new Thread(() -> {
           // phone.sendMail();
            Phone.sendMailStatic();
           // phone.sendMailStatic();
//            phone.sendMail();
        }).start();
        try {
            TimeUnit.MILLISECONDS.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(() -> {
           // phone.sendSMS();
           // phone.sendHello();
            phone2.sendSMS();
            //Phone.sendSMSStatic();
//             phone.sendSMSStatic();
            //phone2.sendSMSStatic();
        }).start();

          try { TimeUnit.MILLISECONDS.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }
    }


    private static class Phone {

        public synchronized void sendMail() {
            try {
                TimeUnit.MILLISECONDS.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("----send email----");
        }

        public static synchronized void sendMailStatic(){
            try {
                TimeUnit.MILLISECONDS.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("----send email static----");
        }

        public synchronized void sendSMS() {
            System.out.println("----send SMS----");
        }

        public static synchronized void sendSMSStatic() {
            System.out.println("----send SMS static----");
        }


        public void sendHello(){
            System.out.println("----send Hello----");
        }
    }
}



